package server.dbInfo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import server.NodeInfo;

public class TableInfo {
	public String schemaName;
	public String tableName;
	public ArrayList<ColumnInfo> columns;  //posortowane wzg nazwy kolumny
	public ArrayList<KeyInfo> keys; 		//posortowane wzg nazwy klucza
	
	public TableInfo(){
		columns = new ArrayList<ColumnInfo>();
		keys = new ArrayList<KeyInfo>();
	}
	
	@Override
	public boolean equals(Object obj){
		if(!(obj instanceof TableInfo) || obj == null)
			return false;
		
		TableInfo toCompare = (TableInfo) obj;
		
		if(!this.schemaName.equals(toCompare.schemaName) 
		   || !this.tableName.equals(toCompare.tableName)
		   || this.columns.size() != toCompare.columns.size()
//		   || first.keys.size() != second.keys.size()
		   )
		{
			return false;
		}
			
		for(int i = 0; i < this.columns.size(); i ++) {
			if(!this.columns.get(i).equals(toCompare.columns.get(i)))
				return false;
		}

//		for(int i = 0; i < this.keys.size(); i ++) {
//			if(!this.keys.get(i).equals(second.keys.get(i)) )
//				return false;
//		}		
				
		return true;
	}
	
	private static final String infoQuery = 
		"SELECT table_schema, table_name, column_name, is_nullable, data_type, character_maximum_length, " +
		"numeric_precision, numeric_scale " +
		"FROM information_schema.columns " +
		"WHERE table_schema <> 'information_schema' and table_schema <> 'pg_catalog' " +
		"ORDER BY table_schema, table_name, column_name";
	
	public static ArrayList<TableInfo> load(NodeInfo info) throws SQLException{	
		ArrayList<TableInfo> result = new ArrayList<TableInfo>();
		Connection connection = null;
		
		try {
			connection = DriverManager.getConnection(info.getUrl(), info.getUser(), info.getPassword());
			Statement sqlStatement = connection.createStatement();			
			ResultSet resultData = sqlStatement.executeQuery(infoQuery);	
			TableInfo t = new TableInfo(); //wydmuszka na potrzeby pierwszej iteracji petli ponizej
		    t.schemaName = t.tableName = "";
			
		    while (resultData.next()) {
				String schema = resultData.getString(1);
				String tableName = resultData.getString(2);
		    	if(!t.schemaName.equals(schema) || !t.tableName.equals(tableName)) {
		    		t = new TableInfo();
		    		result.add(t);
		    		t.schemaName = resultData.getString("table_schema");
		    		t.tableName = resultData.getString("table_name");
		    	}
		    	
		    	ColumnInfo c = new ColumnInfo();
		    	c.ColumnName = resultData.getString("column_name");
		    	c.isNullable = resultData.getString("is_nullable").equalsIgnoreCase("YES");
		    	c.TypeName = resultData.getString("data_type");
		    	c.MaxCharLength = resultData.getString("character_maximum_length");	
		    	c.Precision = resultData.getString("numeric_precision");
		    	c.Scale = resultData.getString("numeric_scale");
		    	t.columns.add(c);
		    }					
		    
		} catch (SQLException e) {
			//sprobuj zamknac polaczenie i propaguj wyjatek w gore
			if(connection != null) {
				try {
					connection.close();
				} catch (SQLException e1) { e.printStackTrace(); }
			}
			throw e;
		}
		
		return result;		
	}
}
